x86_emulate: protmode_load_seg() cannot load system segments in long mode.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 7 Aug 2009 08:54:43 +0000 (09:54 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 7 Aug 2009 08:54:43 +0000 (09:54 +0100)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/x86_emulate/x86_emulate.c

index de14199b1fd43353baac3658137cf104bcf5a151..8fa5fd400b2c78eec01ce820b9c4fc8d2265fd19 100644 (file)
@@ -1037,8 +1037,17 @@ protmode_load_seg(
         goto raise_exn;
     }
 
-    /* System segments must have the system flag (S) set. */
-    if ( (desc.b & (1u<<12)) == (!is_x86_user_segment(seg) << 12) )
+    if ( !is_x86_user_segment(seg) )
+    {
+        /* System segments must have S flag == 0. */
+        if ( desc.b & (1u << 12) )
+            goto raise_exn;
+        /* We do not support 64-bit descriptor types. */
+        if ( in_longmode(ctxt, ops) )
+            return X86EMUL_UNHANDLEABLE;
+    }
+    /* User segments must have S flag == 1. */
+    else if ( !(desc.b & (1u << 12)) )
         goto raise_exn;
 
     dpl = (desc.b >> 13) & 3;